#include "Logger.hpp"
#include "FileSystem.hpp"
#include "OutputStream.hpp"
#include <Windows.h>

namespace ge {

//----------------------------------------------------------------------------//
// Logger
//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//
Logger::Logger( void )
{
     String _name = FileSystem::AppDir() / FileSystem::MakeName( FileSystem::ShortName( FileSystem::AppName() ), "log" );
     m_log = FileSystem::RewriteFile( _name, false );
}
//----------------------------------------------------------------------------//
Logger::~Logger( void )
{
}
//----------------------------------------------------------------------------//
void Logger::Message( const char* _msg )
{
     if( !_msg ) return;
     
     // write to file
     if( HasInstance() && instance -> m_log )
     {
          instance -> m_log -> Write( _msg, String::Length( _msg ) );
          char _nl = '\n';
          instance -> m_log -> Write( &_nl, 1 );
     }

     // write to console
     String _oem;
     _oem.Reserve( String::Length( _msg ) );
     CharToOemA( _msg, _oem.EditData() );  
     _oem.EndEdit();
     printf( "%s\n", _oem.Data() );
}
//----------------------------------------------------------------------------//
void Logger::FMessage( const char* _msg, ... )
{
     va_list _args;
     va_start( _args, _msg );
     String _str = String::FormatVL( _msg, _args );
     va_end( _args );
     Message( _str );
}
//----------------------------------------------------------------------------//
void Logger::Info( const char* _msg )
{
     Message( String( "- " ) + _msg );
}
//----------------------------------------------------------------------------//
void Logger::FInfo( const char* _msg, ... )
{
     va_list _args;
     va_start( _args, _msg );
     String _str = "- " + String::FormatVL( _msg, _args );
     va_end( _args );
     Message( _str );
}
//----------------------------------------------------------------------------//
void Logger::Warning( const char* _msg )
{
     Message( String( "* " ) + _msg );
}
//----------------------------------------------------------------------------//
void Logger::FWarning( const char* _msg, ... )
{
     va_list _args;
     va_start( _args, _msg );
     String _str = "* " + String::FormatVL( _msg, _args );
     va_end( _args );
     Message( _str );
}
//----------------------------------------------------------------------------//
void Logger::Error( const char* _msg )
{
     Message( String( "! " ) + _msg );
}
//----------------------------------------------------------------------------//
void Logger::FError( const char* _msg, ... )
{
     va_list _args;
     va_start( _args, _msg );
     String _str = "! " + String::FormatVL( _msg, _args );
     va_end( _args );
     Message( _str );
}
//----------------------------------------------------------------------------//
void Logger::Exception( const ge::Exception& _e, const char* _msg )
{
     String _str = "!!! ";
     if( _e.type.NonEmpty() )
     {
          _str += _e.type;
          if( _e.message.NonEmpty() || _e.message.NonEmpty() ) _str += " : ";
     }
     if( _e.message.NonEmpty() ) _str += _e.message + " ";
     if( _e.source.file.NonEmpty() || _e.source.func.NonEmpty() ) _str += "[";
     if( _e.source.file.NonEmpty() )
     {
          _str += _e.source.file + String::Format( "(%d", _e.source.row );
          if( _e.source.col > 0 ) _str += String::Format( ",%d", _e.source.col );
          _str += ")";
          if( _e.source.func.NonEmpty() ) _str += " : ";
     }
     if( _e.source.func.NonEmpty() ) _str += _e.source.func;
     if( _e.source.file.NonEmpty() || _e.source.func.NonEmpty() ) _str += "]";
     if( _msg ){ _str += "\n    "; _str += _msg; };
     Message( _str ); 
}
//----------------------------------------------------------------------------//
void Logger::FException( const ge::Exception& _e, const char* _msg, ... )
{
     va_list _args;
     va_start( _args, _msg );
     String _str = String::FormatVL( _msg, _args );
     va_end( _args );
     Exception( _e, _str );
}
//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//
//
//----------------------------------------------------------------------------//

} // namespace ge
